package com.htdata.iiot.api.tsdb.utils;

import com.htdata.iiot.api.tsdb.config.Configs;
import com.htdata.iiot.api.tsdb.pojo.DeviceStatusData;
import com.htiiot.common.config.ConfigFactory;
import net.opentsdb.core.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

public class QueryDstatus {
    private static final Logger logger = LogManager.getLogger(QueryDstatus.class);
    private TSDB tsdb;
    public QueryDstatus(){
        initParamters();
    }

    private void initParamters() {
        logger.info("initing dstatus TSDB paramters");
        if(tsdb == null){
            tsdb = new TSDBBuilder(ConfigFactory.getConfigMgr(), Configs.DstatusTSDBConfig.CONFIG_SECTION).createTSDB();
        }
    }

    public DeviceStatusData[] getTSData(String did, Date startTime, Date endTime, String downsample) throws Exception {
        Query[] tsdbQueries = null;
        try {
            TSQuery query = new TSQueryBuilder().setStartTime(startTime).setEndTime(endTime)
                    .setMetricName(did).setDownsample(downsample).build();
            query.validateAndSetQuery();
            tsdbQueries = query.buildQueries(tsdb);
        } catch (Exception e) {
            logger.error(e.getMessage());
            throw e;
        }
        return getDataFromQuery(tsdbQueries, startTime, endTime);
    }

    private DeviceStatusData[] getDataFromQuery(Query[] tsdbqueries, Date startTime, Date endTime) {
        ArrayList<DataPoints> result = new ArrayList<DataPoints>();
        if (tsdbqueries != null) {
            int nqueries = tsdbqueries.length;
            for (int i = 0; i < nqueries; i++) {
                try {
                    DataPoints[] dps = tsdbqueries[i].run();
                    result.addAll(Arrays.asList(dps));
                } catch (Exception ex) {
                    logger.error("error retrive data ", ex);
                }
            }
        }
        List<DeviceStatusData> dpResult = new ArrayList<DeviceStatusData>();
        long startTimeL = startTime.getTime();
        long endTimeL = endTime.getTime();
        for (DataPoints dps : result) {
            SeekableView it = dps.iterator();
            while (it.hasNext()) {
                net.opentsdb.core.DataPoint dp = it.next();
                long ts = dp.timestamp();
                if (ts >= startTimeL && ts < endTimeL) {
                    DeviceStatusData data = new DeviceStatusData();
                    data.setTags(dps.getTags());
                    data.setDid(dps.metricName());
                    data.setValue((long)dp.doubleValue());
                    data.setTs(dp.timestamp());
                    dpResult.add(data);
                }
            }

        }
        return dpResult.toArray(new DeviceStatusData[0]);
    }
}
